package ar.edu.utn.frba.gdaia.src.swing.gui;

import java.awt.GridBagConstraints;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.BevelBorder;
import javax.swing.SwingUtilities;

import ar.edu.utn.frba.gdaia.src.action.Command;
import ar.edu.utn.frba.gdaia.src.domain.Canal;
import ar.edu.utn.frba.gdaia.src.domain.Concepto;
import ar.edu.utn.frba.gdaia.src.externalinterface.Mensaje;
import ar.edu.utn.frba.gdaia.src.externalinterface.Notificable; 
import ar.edu.utn.frba.gdaia.src.externalinterface.TextInterface;;



public class GdaiaGuiFrame extends javax.swing.JFrame implements Runnable, Notificable{
    
	private static final long serialVersionUID = 1L;
	private JRadioButton botonDespierto = new JRadioButton();
    private JRadioButton botonDormido = new JRadioButton();
    
    private JTextField entrada = new JTextField();
    private JTextField Txtvideo = new JTextField();
    private JTextField Txtaudio = new JTextField();
    private JTextField Txtimagen = new JTextField();
    
    private JTextArea salida = new JTextArea("Salida GDAIA:" + '\n');
    private JTextArea textareaEstado = new JTextArea();
    
    private JLabel jLabel1 = new JLabel();
    private JLabel jLabel2 = new JLabel();
    private JLabel jLabel3 = new JLabel();
    private JLabel jLabel4 = new JLabel();
    private JLabel theImage= new JLabel("");
    
    private JCheckBox ChkTexto = new JCheckBox();
    private JCheckBox ChkVideo = new JCheckBox();
    private JCheckBox ChkAudio = new JCheckBox();
    private JCheckBox ChkImagen = new JCheckBox();
    
    private JScrollPane jScrollPane1 = new JScrollPane();
   
    private TextInterface interfaceGUI;

    // Constantes
    private static final String TIP_INGRESE_COMANDO = "Ingrese Comando...";
    private static final String TIP_ESTADO_SISTEMA = "Estado del sistema";
    private static final String TITULO_VENTANA = "GDAIA v1.0  UTN-FRBA";
    private static final String DESCRIPCION_ESTADO = "Estado del Sistema:";
    private static final String ESTADO_DESPIERTO = "DESPIERTO";
    private static final String ESTADO_DORMIDO = "DORMIDO";
    
    // paneles
	private javax.swing.JPanel entrada_Panel;
	private javax.swing.JPanel salida_Panel;
	private javax.swing.JPanel status_Panel;
	private javax.swing.JPanel radio_Panel;
	private javax.swing.JScrollPane entrada_scroll;
	private javax.swing.JScrollPane salida_scroll;
    
    private JButton ingresar = new JButton();
    
    private JButton jButton2 = new JButton();
    private JButton jButton3 = new JButton();
    private JButton jButton4 = new JButton();
    private JPanel imagen1 = new JPanel();

    public GdaiaGuiFrame() {
        try {
            jbInit();
        } catch (Exception e) {
        	JOptionPane.showMessageDialog(null,e.getMessage());
        }
    }
    
    public GdaiaGuiFrame(TextInterface interfaceGUI) {
    	this.interfaceGUI = interfaceGUI;
    	// agregar a la misma ventana como observador
    	this.interfaceGUI.setObserver(this);
    	
    }

    private void jbInit() throws Exception {
        //Se declaran los paneles: son 3
        //declaracion del panel para la entrada
        entrada_Panel = new JPanel();
        //declaracion del panel para la salida
        salida_Panel = new JPanel();
        //declaracion del panel para la barra de estado
        status_Panel = new JPanel();
        
        //panel para los radiobuttons y el boton ingreso
        radio_Panel = new JPanel();
        
		salida_scroll = new javax.swing.JScrollPane();
		entrada_scroll = new javax.swing.JScrollPane();
        
		this.setLayout(new java.awt.GridBagLayout());
		salida_Panel.setLayout(new java.awt.GridBagLayout());
        // seteo el listener que actua cuando se cierra la ventana
		
        this.addWindowListener(new java.awt.event.WindowAdapter() {
        	public void windowClosing(java.awt.event.WindowEvent evt){
        	exitForm(evt);
        }
        });
    
        // configuracion del panel de salida
        //salida_Panel.setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        salida.setEditable(true);
        salida.setVisible(true);
        salida_scroll.setViewportView(salida);
        //c.gridwidth = 1;
        //c.gridheight = 1;
        //c.weightx = 0.9;
        //c.weighty = 0.9;
        c.gridx = 0;
        c.gridy = 0;
        salida_Panel.add(salida,c);
        
        //agrego los 2 radiobuttons y el boton ingreso
        //c.gridheight = GridBagConstraints.RELATIVE;
        //c.gridwidth = GridBagConstraints.RELATIVE;
        //c.weightx = 0.3;
        //c.weighty = 0.1;
        c.gridx = 0;
        c.gridy = 1;
        c.gridheight = GridBagConstraints.RELATIVE;
        c.gridwidth = GridBagConstraints.RELATIVE;
        botonDespierto.setText("DESPIERTO");
        botonDespierto.setSelected(true);
        botonDespierto.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        BtnDespierto_actionPerformed();
                    }
                });
        salida_Panel.add(botonDespierto,c);

        c.gridheight = GridBagConstraints.REMAINDER;
        c.gridwidth = GridBagConstraints.REMAINDER;
        //c.weightx = 0.3;
        //c.weighty = 0.1;
        c.gridx = 1;
        c.gridy = 1;
        botonDormido.setText("DORMIDO");
        botonDormido.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        BtnDormido_actionPerformed();
                    }
                }); 
        
        salida_Panel.add(botonDormido,c);
        
       //agrego el boton ingresar
        ingresar.setMnemonic('I');
        ingresar.setText("Ingreso");
        //c.gridy =8;
        //c.gridx = 0;
        //c.weightx = 0.4;
        //c.weighty = 0.1;
        
       ingresar.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        Ingresar_actionPerformed(e);
                    }
                });
        ingresar.addMouseListener(new MouseAdapter() {
        	public void mouseClicked(MouseEvent evt) {
        		botonMouseClicked(evt);
        	}
        });
       salida_Panel.add(ingresar,c);
        this.add(salida_Panel);
  

		//configuracion del panel de entrada
		//Esto es solamente para la entrada por teclado
		//entrada_Panel.setLayout(new java.awt.GridLayout(1, 2));
		entrada.setToolTipText(TIP_INGRESE_COMANDO);
        //agrego el listener al textarea para procesar cuando se
        //oprime una tecla
        entrada.addKeyListener(new KeyAdapter() {
        	public void keyPressed(KeyEvent evt) {
        		entradaKeyPressed(evt);
        	}
        });
		// Fin de la entrada por teclado
		    
       
        jLabel1.setText("Entrada por teclado");
        jLabel1.setBounds(new Rectangle(425, 15, 115, 25));
        entrada.setBounds(new Rectangle(405, 40, 155, 35));
        entrada.setAutoscrolls(false);
        jLabel2.setText("Entrada por Video");
        jLabel2.setBounds(new Rectangle(430, 85, 105, 20));
        Txtvideo.setBounds(new Rectangle(405, 105, 120, 20));
        Txtvideo.setEditable(false);
        jLabel3.setText("Entrada por audio");
        jLabel3.setBounds(new Rectangle(430, 145, 105, 20));
        Txtaudio.setBounds(new Rectangle(405, 170, 120, 20));
        Txtaudio.setEditable(false);
        jLabel4.setText("Entrada por Imagen");
        jLabel4.setBounds(new Rectangle(430, 210, 110, 15));
        Txtimagen.setBounds(new Rectangle(405, 235, 120, 20));
        Txtimagen.setEditable(false);
        
    
        ChkTexto.setBounds(new Rectangle(400, 15, 20, 20));
        ChkTexto.setSelected(true);
        ChkTexto.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        ChkTexto_actionPerformed(e);
                    }
                });
        ChkVideo.setBounds(new Rectangle(400, 85, 20, 20));
        ChkVideo.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        ChkVideo_actionPerformed(e);
                    }
                });
        ChkAudio.setBounds(new Rectangle(400, 145, 20, 20));
        ChkAudio.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        ChkAudio_actionPerformed(e);
                    }
                });
        ChkImagen.setBounds(new Rectangle(400, 210, 20, 20));
        ChkImagen.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        ChkImagen_actionPerformed(e);
                    }
                });
        jScrollPane1.setBounds(new Rectangle(15, 10, 365, 345));
        textareaEstado.setBounds(new Rectangle(0, 405, 580, 25));
        textareaEstado.setEditable(false);
        textareaEstado.setBackground(Color.LIGHT_GRAY);
        
        // Barra de estado
        textareaEstado.setText(DESCRIPCION_ESTADO + " " + ESTADO_DESPIERTO + 
                               "\n");
        
        
        jButton2.setText("...");
        jButton2.setBounds(new Rectangle(530, 105, 35, 20));
        jButton3.setText("...");
        jButton3.setBounds(new Rectangle(530, 170, 35, 20));
        jButton4.setText("...");
        jButton4.setBounds(new Rectangle(530, 235, 35, 20));
        jButton4.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        jButton4_actionPerformed(e);
                    }
                });
        imagen1.setBounds(new Rectangle(390, 265, 180, 125));

        // Create a panel to hold the image
        JPanel imagePanel = new JPanel();
        imagePanel.setLayout(new BorderLayout());
        imagePanel.setBorder(new BevelBorder(BevelBorder.LOWERED));
        JScrollPane scroller = new JScrollPane(theImage);
        scroller.getVerticalScrollBar().setUnitIncrement(10);
        scroller.getHorizontalScrollBar().setUnitIncrement(10);
        imagePanel.add(scroller, BorderLayout.CENTER);
        imagen1.setLayout(new BorderLayout()); 
        imagen1.add(imagePanel,BorderLayout.CENTER);

    }

    private void BtnDespierto_actionPerformed() {
        boolean selected = botonDormido.isSelected();

        if (selected == true) {
        	botonDespierto.setSelected(true);
        	botonDormido.setSelected(false);
        }
    }

    private void BtnDormido_actionPerformed() {
        boolean selected = botonDespierto.isSelected();

        if (selected == true) {
        	botonDormido.setSelected(true);
        	botonDespierto.setSelected(false);
        }
    }

    private void ChkTexto_actionPerformed(ActionEvent e) {

        if (ChkTexto.isSelected() == true) {
            entrada.setEnabled(true);
            entrada.setEditable(true);
        } else {
        	entrada.setEnabled(false);
        	entrada.setEditable(false);
        }

    }

    private void ChkVideo_actionPerformed(ActionEvent e) {
        if (ChkVideo.isSelected() == true) {
            JOptionPane.showMessageDialog(null, "Funcion no implementada");
        }
    }

    private void ChkAudio_actionPerformed(ActionEvent e) {
        if (ChkAudio.isSelected() == true) {
            JOptionPane.showMessageDialog(null, "Funcion no implementada");
        }
    }

    private void ChkImagen_actionPerformed(ActionEvent e) {
        if (ChkImagen.isSelected() == false) {
            jButton4.setEnabled(false);
            Txtimagen.setEditable(false);
        } else
            jButton4.setEnabled(true);
        Txtimagen.setEditable(true);
    }

    //TODO: Darle funcionalidad a la pantalla
    private void Ingresar_actionPerformed(ActionEvent e) {
        if (ChkTexto.isSelected() == true) {
            salida.append(entrada.getText() + "\n");
            entrada.setText("");
        }
        if (ChkAudio.isSelected() == true)
            JOptionPane.showMessageDialog(null, 
                                          "Audio: Funcion no implementada");
        if (ChkImagen.isSelected() == true)
            ;//
        if (ChkVideo.isSelected() == true)
            JOptionPane.showMessageDialog(null, 
                                          "Video: Funcion no implementada");
        if (ChkAudio.isSelected() == false && 
            ChkImagen.isSelected() == false && 
            ChkVideo.isSelected() == false && ChkTexto.isSelected() == false)
            JOptionPane.showMessageDialog(null, 
                                          "Por lo menos algun metodo de entrada debe estar seleccionado");
    }

    // Adicion de soporte para leer imagenes JPG y GIF

    private void jButton4_actionPerformed(ActionEvent e) {
        JFileChooser archivo = new JFileChooser();
        File path;
 
        archivo.addChoosableFileFilter(new ImageFilter());
        archivo.showOpenDialog(GdaiaGuiFrame.this);
        path = archivo.getSelectedFile();
        Txtimagen.setText(path.toString());


        theImage.setIcon(new ImageIcon(Txtimagen.getText()));
   }

    
    private void entradaKeyPressed(KeyEvent evt) {
    	int id = evt.getID();
    	if (id == KeyEvent.KEY_PRESSED) {
    		char c = evt.getKeyChar();
    		if (c == '\n') {
    			Traspaso();
    		}
    	}
    }

    private void Traspaso() {
    	String s_entrada = null;
    	String aux = null;
    	String aux1 = null;
    	
    	entrada.selectAll();
    	aux = aux1 = entrada.getSelectedText();
    	if (aux != null) {
    		if (aux.startsWith("\n") && aux.length() >= 2)
    			aux1 = aux.substring(1,aux.length());
    		if (aux.endsWith("\n")) {
    			s_entrada = aux1.substring(0,aux1.length() -1);
    			if (s_entrada.length() >= 2) {
    				salida.append(s_entrada + "\n");
    				this.enviarPorInterface(aux);
    			}
    		}
    		else {
    			salida.append(aux1 + "\n");
    			this.enviarPorInterface(aux);
    		}
    	}
    	entrada.setText(null);
    	salida.repaint();
    	entrada.repaint();
    		
    }

    private void enviarPorInterface(String aux) {
    	List<String> palabrasLeidas = new ArrayList<String>();
    	StringTokenizer token = new StringTokenizer(aux);
    	while (token.hasMoreTokens()) {
    		palabrasLeidas.add(token.nextToken().trim());
    	}
    	interfaceGUI.putFromUIToMind(new Mensaje(palabrasLeidas, Canal.TECLADO));
    }

    public void update()
    {
    	Runnable doWorkRunnable = new Runnable() {
    		public void run() {
    			Mensaje msj = interfaceGUI.getFromMindToUI();
    			Object payLoad = msj.getPayload();
    			Canal canalIngreso = msj.getCanalIngreso();
    			
    			// el mensaje puede contener un texto
    			if (canalIngreso == Canal.TECLADO) {
    				// es un texto enviado por teclado
    				salida.append(payLoad.toString() + "\n");
    				salida.repaint();
    				entrada.repaint();
    			}
    			if (canalIngreso == Canal.INTERNO) {
    				if (payLoad.equals(Command.CAMBIAR_A_DESPIERTO)) {
						// suspendo momentaneamente disparar los eventos por
						// cambio de estado del radiobutton (itemstatechange)
						ItemListener il[] = botonDormido.getItemListeners();
						for (int i = 0; i < il.length; i++) {
							botonDormido.removeItemListener(il[i]);
						}
						// cambio en la GUI al estado despierto
						botonDormido.setSelected(true);
						// restauro nuevamente los eventos por cambio de estado
						// del radiobutton (itemstatechange)
						for (int i = 0; i < il.length; i++) {
							botonDormido.addItemListener(il[i]);
						}
						// informo en el tablero el nuevo estado
						textareaEstado.append(TIP_ESTADO_SISTEMA + ": "
								+ ESTADO_DESPIERTO + "\n");
					} else {
						// por ejemplo si desde la regla dummy del despierto nos
						// envian algun mensaje
						// textareaEstado.append(payLoad.toString() + "\n");
					}
					textareaEstado.repaint();
				}
			}
		};
		SwingUtilities.invokeLater(doWorkRunnable);
	}

    public void run() {
    	this.setTitle(TITULO_VENTANA);
    	this.setVisible(true);
    }

    public void exitForm(java.awt.event.WindowEvent evt) {
    	//interfaceGUI.putFromUIToMind(new Mensaje(Command.FINALIZAR_PROGRAMA,Canal.INTERNO));
    	//this.dispose();
    }
    
    public void botonMouseClicked(MouseEvent e) {
    	Traspaso();
    }

    public static void main(String args[]) {
    	GdaiaGuiFrame ventana = new GdaiaGuiFrame();
    	ventana.setTitle(TITULO_VENTANA);
    	ventana.setSize(450,260);
    	ventana.setVisible(true);
    }
    
	private JRadioButton getJRadioButton() {
		if (botonDespierto == null) {
			botonDespierto = new JRadioButton();
			botonDespierto.setSelected(true);
			botonDespierto.setText("Despierto");
			botonDespierto.addItemListener(new java.awt.event.ItemListener() {
				public void itemStateChanged(java.awt.event.ItemEvent e) {
					// cambiamos de estado al cerebro
					if (botonDespierto.isSelected()) {
						// TODO deber�amos informarle al cerebro del cambio de
						// estado: Despierto
						interfaceGUI.putFromUIToMind(new Mensaje(
								Concepto.AWAKE, Canal.INTERNO));
						// this.entrada.requestFocus();
					} else {
						// // TODO deber�amos informarle al cerebro del cambio
						// de estado: Dormido
						textareaEstado.append(TIP_ESTADO_SISTEMA + ": "
								+ ESTADO_DORMIDO + "\n");
						interfaceGUI.putFromUIToMind(new Mensaje(
								Concepto.DORMIDO, Canal.INTERNO));
						// this.entrada.requestFocus();
					}
				}
			});
		}
		return botonDespierto;
	}

	private JRadioButton getJRadioButton1() {
		if (botonDormido == null) {
			botonDormido = new JRadioButton();
			botonDormido.setText("Dormido");
		}
		return botonDormido;
	}
}

